package com.action.gulimall.seckill.config;

import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.ClusterServersConfig;
import org.redisson.config.Config;
import org.redisson.config.SentinelServersConfig;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.StringUtils;

/**
 * @author sl shilun217@qq.com
 * @Deacription Redisson配置类
 * @date 2021/06/20/18:04
 **/
@Slf4j
@Configuration
@EnableConfigurationProperties(value={MyRedissonConfig.RedisConfig.class})
public class MyRedissonConfig {


    @Bean(destroyMethod="shutdown")
    public RedissonClient getRedissonClient(RedisConfig redisConfig) throws CostomException {
        Config config = new Config();
        if(!StringUtils.isEmpty(redisConfig.getMode())){
            if(redisConfig.getMode().equals(RedisMode.SingleMode.getModeStr())){
                log.info("以单机模式启动");
                String[] addresss = redisConfig.getAddress().split(",");
                config.useSingleServer().setAddress((redisConfig.openssl?"rediss://":"redis://")+addresss[0]);
            }else if(redisConfig.getMode().equals(RedisMode.SentinelMode.getModeStr())){
                log.info("以哨兵模式启动");
                String[] addresss = redisConfig.getAddress().split(",");
                if(redisConfig.getSentinel()==null){
                    throw  new CostomException("哨兵模式下,必须配置masterName");
                }
                SentinelServersConfig sentinelServersConfig = config.useSentinelServers()
                        .setMasterName(redisConfig.getSentinel().getMasterName());
                //可以用"rediss://"来启用SSL连接
                for (String address:addresss){
                    sentinelServersConfig.addSentinelAddress((redisConfig.openssl?"rediss://":"redis://")+address);
                }
            }else if(redisConfig.getMode().equals(RedisMode.ClusterMode.getModeStr())){
                log.info("以集群模式启动");
                String[] addresss = redisConfig.getAddress().split(",");
                ClusterServersConfig clusterServersConfig = config.useClusterServers();
                Integer scanInterval = 2000;
                if(redisConfig.getCluster()!=null){
                    scanInterval=redisConfig.getCluster().getScanInterval();
                }
                clusterServersConfig.setScanInterval(scanInterval);// 集群状态扫描间隔时间，单位是毫秒
                //可以用"rediss://"来启用SSL连接
                for (String address:addresss){
                    clusterServersConfig.addNodeAddress((redisConfig.openssl?"rediss://":"redis://")+address);
                }
            }
        }else{
            log.info("默认以单机模式启动");
            config.useSingleServer().setAddress("redis://127.0.0.1:6379");
        }
        RedissonClient redisson = Redisson.create(config);
        return redisson;
    }

    @ConfigurationProperties(value = "redis.config")
    @Data
    class RedisConfig{
        String address;
        String mode;
        boolean openssl;
        Cluster cluster;
        Sentinel sentinel;
    }

    @Data
    private class Cluster{
        Integer scanInterval;
    }

    @Data
    private class Sentinel{
        String masterName;
    }

    private static enum RedisMode{
        SingleMode("single"),ClusterMode("cluster"),SentinelMode("sntinel");
        String modeStr;
        RedisMode(String mode){
            modeStr=mode;
        }

        public String getModeStr() {
            return modeStr;
        }
    }

    private class CostomException extends Exception{

        public CostomException(String message){
            super(message);
        }
    }
}
